123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using UnityEditor;
- using UnityEngine;
- namespace ExternPropertyAttributes.Editor
- {
- // Applied in `CustomInspectorDefinitions.cs`.
- public class ExternalCustomInspector : UnityEditor.Editor
- {
- private List<SerializedProperty> _serializedProperties = new List<SerializedProperty>();
- private IEnumerable<FieldInfo> _nonSerializedFields;
- private IEnumerable<PropertyInfo> _nativeProperties;
- private IEnumerable<MethodInfo> _methods;
- private Dictionary<string, SavedBool> _foldouts = new Dictionary<string, SavedBool>();
- private void OnEnable()
- {
- _nonSerializedFields = ReflectionUtility.GetAllFields(
- target, f => f.GetCustomAttributes(typeof(ShowNonSerializedFieldAttribute), true).Length > 0);
- _nativeProperties = ReflectionUtility.GetAllProperties(
- target, p => p.GetCustomAttributes(typeof(ShowNativePropertyAttribute), true).Length > 0);
- _methods = ReflectionUtility.GetAllMethods(
- target, m => m.GetCustomAttributes(typeof(ButtonAttribute), true).Length > 0);
- }
- public override void OnInspectorGUI()
- {
- GetSerializedProperties(ref _serializedProperties);
- bool anyExternalCustomAttribute = _serializedProperties.Any(p => PropertyUtility.GetAttribute<ICustomAttribute>(p) != null);
- if (!anyExternalCustomAttribute)
- {
- DrawDefaultInspector();
- }
- else
- {
- DrawSerializedProperties();
- }
- DrawNonSerializedFields();
- DrawNativeProperties();
- DrawButtons();
- }
- private void GetSerializedProperties(ref List<SerializedProperty> outSerializedProperties)
- {
- outSerializedProperties.Clear();
- using (var iterator = serializedObject.GetIterator())
- {
- if (iterator.NextVisible(true))
- {
- do
- {
- outSerializedProperties.Add(serializedObject.FindProperty(iterator.name));
- }
- while (iterator.NextVisible(false));
- }
- }
- }
- private void DrawSerializedProperties()
- {
- serializedObject.Update();
- // Draw non-grouped serialized properties
- foreach (var property in GetNonGroupedProperties(_serializedProperties))
- {
- if (property.name.Equals("m_Script", System.StringComparison.Ordinal))
- {
- using (new EditorGUI.DisabledScope(disabled: true))
- {
- EditorGUILayout.PropertyField(property);
- }
- }
- else
- {
- ExternalCustomEditorGUI.PropertyField_Layout(property, includeChildren: true);
- }
- }
- // Draw grouped serialized properties
- foreach (var group in GetGroupedProperties(_serializedProperties))
- {
- IEnumerable<SerializedProperty> visibleProperties = group.Where(p => PropertyUtility.IsVisible(p));
- if (!visibleProperties.Any())
- {
- continue;
- }
- ExternalCustomEditorGUI.BeginBoxGroup_Layout(group.Key);
- foreach (var property in visibleProperties)
- {
- ExternalCustomEditorGUI.PropertyField_Layout(property, includeChildren: true);
- }
- ExternalCustomEditorGUI.EndBoxGroup_Layout();
- }
- // Draw foldout serialized properties
- foreach (var group in GetFoldoutProperties(_serializedProperties))
- {
- IEnumerable<SerializedProperty> visibleProperties = group.Where(p => PropertyUtility.IsVisible(p));
- if (!visibleProperties.Any())
- {
- continue;
- }
- if (!_foldouts.ContainsKey(group.Key))
- {
- _foldouts[group.Key] = new SavedBool($"{target.GetInstanceID()}.{group.Key}", false);
- }
- _foldouts[group.Key].Value = EditorGUILayout.Foldout(_foldouts[group.Key].Value, group.Key, true);
- if (_foldouts[group.Key].Value)
- {
- foreach (var property in visibleProperties)
- {
- ExternalCustomEditorGUI.PropertyField_Layout(property, true);
- }
- }
- }
- serializedObject.ApplyModifiedProperties();
- }
- private void DrawNonSerializedFields(bool drawHeader = false)
- {
- if (_nonSerializedFields.Any())
- {
- if (drawHeader)
- {
- EditorGUILayout.Space();
- EditorGUILayout.LabelField("Non-Serialized Fields", GetHeaderGUIStyle());
- ExternalCustomEditorGUI.HorizontalLine(
- EditorGUILayout.GetControlRect(false), HorizontalLineAttribute.DefaultHeight, HorizontalLineAttribute.DefaultColor.GetColor());
- }
- foreach (var field in _nonSerializedFields)
- {
- ExternalCustomEditorGUI.NonSerializedField_Layout(serializedObject.targetObject, field);
- }
- }
- }
- private void DrawNativeProperties(bool drawHeader = false)
- {
- if (_nativeProperties.Any())
- {
- if (drawHeader)
- {
- EditorGUILayout.Space();
- EditorGUILayout.LabelField("Native Properties", GetHeaderGUIStyle());
- ExternalCustomEditorGUI.HorizontalLine(
- EditorGUILayout.GetControlRect(false), HorizontalLineAttribute.DefaultHeight, HorizontalLineAttribute.DefaultColor.GetColor());
- }
- foreach (var property in _nativeProperties)
- {
- ExternalCustomEditorGUI.NativeProperty_Layout(serializedObject.targetObject, property);
- }
- }
- }
- private void DrawButtons(bool drawHeader = false)
- {
- if (_methods.Any())
- {
- if (drawHeader)
- {
- EditorGUILayout.Space();
- EditorGUILayout.LabelField("Buttons", GetHeaderGUIStyle());
- ExternalCustomEditorGUI.HorizontalLine(
- EditorGUILayout.GetControlRect(false), HorizontalLineAttribute.DefaultHeight, HorizontalLineAttribute.DefaultColor.GetColor());
- }
- foreach (var method in _methods)
- {
- ExternalCustomEditorGUI.Button(serializedObject.targetObject, method);
- }
- }
- }
- private static IEnumerable<SerializedProperty> GetNonGroupedProperties(IEnumerable<SerializedProperty> properties)
- {
- return properties.Where(p => PropertyUtility.GetAttribute<IGroupAttribute>(p) == null);
- }
- private static IEnumerable<IGrouping<string, SerializedProperty>> GetGroupedProperties(IEnumerable<SerializedProperty> properties)
- {
- return properties
- .Where(p => PropertyUtility.GetAttribute<BoxGroupAttribute>(p) != null)
- .GroupBy(p => PropertyUtility.GetAttribute<BoxGroupAttribute>(p).Name);
- }
- private static IEnumerable<IGrouping<string, SerializedProperty>> GetFoldoutProperties(IEnumerable<SerializedProperty> properties)
- {
- return properties
- .Where(p => PropertyUtility.GetAttribute<FoldoutAttribute>(p) != null)
- .GroupBy(p => PropertyUtility.GetAttribute<FoldoutAttribute>(p).Name);
- }
- private static GUIStyle GetHeaderGUIStyle()
- {
- GUIStyle style = new GUIStyle(EditorStyles.centeredGreyMiniLabel);
- style.fontStyle = FontStyle.Bold;
- style.alignment = TextAnchor.UpperCenter;
- return style;
- }
- }
- }
|